package ro.upt.ac.cstaicu.analyze;

import java.util.ArrayList;
import java.util.Collection;


import ro.upt.ac.cstaicu.execution.Executor;
import ro.upt.ac.cstaicu.execution.TestResult;

/**
 * It models a function, a predicate, a class or a basic block. Each entity has
 * an id and a reference to the tests that executed it. It also computes the
 * number of passed/failed tests that executed it.
 * 
 * @author Cristian-Alexandru STAICU
 * 
 */
public class Entity implements Comparable<Entity> {

	/**
	 * Possible value for the type variable
	 */
	public static final int PREDICATE = 0;
	/**
	 * Possible value for the type variable
	 */
	public static final int FUNCTION = 1;
	/**
	 * Possible value for the type variable
	 */
	public static final int CLASS = 2;
	/**
	 * Possible value for the type variable
	 */
	public static final int BASIC_BLOCK = 3;

	/**
	 * The identification number of the entity
	 */
	public final IContext context;
	/**
	 * The type of the entity (one of the one defined in the current class).
	 */
	public final int type;

	private Collection<TestResult> tests = new ArrayList<TestResult>();
	
	private Collection<TestResult> passedTests = new ArrayList<TestResult>();
	private Collection<TestResult> failedTests = new ArrayList<TestResult>();

	/**
	 * Initializes the current entity. If the type is not one of the ones
	 * defined in this class an {@link IllegalArgumentException} is thrown.
	 * 
	 * @param id
	 *            - the id of the entity
	 * @param type
	 *            - the type of the entity
	 */
	public Entity(IContext context, int type) {
		this.context = context;
		if (type < 0 || type > 3)
			throw new IllegalArgumentException();
		this.type = type;
	}

	/**
	 * Adds the current test to the list of tests that executed the entity.
	 * 
	 * @param test
	 *            current test
	 */
	public void addTestResult(TestResult test) {
		tests.add(test);
		if (test.result == Executor.TEST_PASSED)
			passedTests.add(test);
		else 
			failedTests.add(test);
	}
	
	public int compareTo(Entity o) {
		return getId() - o.getId();
	}
	
	@Override
	public String toString() {
		return context + " " + failedTests + " " + passedTests;
	}
	
	private int getId() {
		return context.getId();
	}

	public int getNoPassed() {
		return passedTests.size();
	}
	
	public int getNoFailed() {
		return failedTests.size();
	}

	public boolean reachedByTest(TestResult error) {
		return failedTests.contains(error) || passedTests.contains(error);
	}
	
	

}
